using System;
using System.Collections;
using System.Collections.Generic;

using Peradigm.Framework.Domain.Collections;
using Peradigm.Framework.Domain.Collections.Generic;
using Peradigm.Framework.Domain.Security;

using Liberty.Application.CaseManagement;
using Liberty.Application.GrantManagement;
using Liberty.Domain.CaseManagement;
using Liberty.Domain.GrantManagement;
using Liberty.Domain.NoteManagement;
using Liberty.Domain.ServiceMemberManagement;
using Liberty.Persistence.CaseManagement;
using Liberty.Persistence.GrantManagement;
using Liberty.Persistence.Kernel;
using Liberty.Persistence.NoteManagement;

namespace Liberty.Application.ServiceMemberManagement
{
    [Serializable]
    public class ServiceMemberController : AbstractController
    {
        #region Constants
        private const string
            DEFAULT_NOTES_SORT = "DateCreated";
        #endregion

        #region Event Handlers
        #endregion

        #region Methods
        public List<Branch> AllBranches()
        {
            return this.ServiceBroker.ServiceBranches();
        }

        public List<Rank> RanksFor( Branch branch )
        {
            List<Rank> ranks = new List<Rank>();
            if( branch != null )
            {
                ranks = this.ServiceBroker.RanksFor( branch );
            }
            return ranks;
        }

        public Branch BranchWith( long branchID )
        {
            return this.ServiceBroker.ServiceBranchWith( branchID );
        }

        public ServiceMember NewServiceMemberFor( User volunteer )
        {
            ServiceMember newServiceMember = new ServiceMember();
            CaseController caseController = new CaseController();
            Case newCase = caseController.NewCaseFor( volunteer );
            newServiceMember.AddCase( newCase );
            GrantController grantController = new GrantController();
            newCase.AddGrant( grantController.NewGrant() );
            return newServiceMember;

            /*#warning Temporarelly replacing with an existing service member to test Wizard
            ServiceMember serviceMember = this.ServiceMemberWith( 12 );
            CaseBroker caseBroker = new CaseBroker( this.ConnectionString );
            List<Case> cases = caseBroker.CasesFor( serviceMember );
            Case aCase = cases[0];
            serviceMember.AddCase( aCase  );
            GrantController grantController = new GrantController();
            aCase.AddGrant( grantController.NewGrant() );

            return serviceMember;*/
        }

        public List<ServiceMember> ServiceMembersMatchingCriteria( ServiceMemberSearchCriteria serviceMemberSearchCriteria )
        {
            return this.PersonBroker.ServiceMembersMatching( serviceMemberSearchCriteria );
        }

        public ServiceMember ServiceMemberWith( long serviceMemberID )
        {
            return this.PersonBroker.ServiceMemberWith( serviceMemberID );
        }

        public List<Note> NotesFrom( ServiceMember serviceMember )
        {
            List<Note> notes = new List<Note>( serviceMember.Notes );
            if( notes.Count == 0 )
            {
                notes = this.NotesFor( serviceMember );
            }
            return notes;           
        }

        public List<Case> CasesFrom( ServiceMember serviceMember )
        {
            List<Case> cases = new List<Case>( serviceMember.Cases );
            if( cases.Count == 0 )
            {
                cases = this.CasesFor( serviceMember );
            }
            return cases;
        }

        public List<Grant> GrantsFrom( ServiceMember serviceMember )
        {
            List<Grant> grants = new List<Grant>( serviceMember.Grants );
            if( grants.Count == 0 )
            {
                grants = this.GrantsFor( serviceMember );
            }
            return grants;
        }

        public Note SaveNote( ServiceMember serviceMember, Note note )
        {
            NoteBroker noteBroker = new NoteBroker( this.ConnectionString );
            Note newNote = noteBroker.SaveNote( serviceMember, note );
            serviceMember.AddNote( newNote );

            return newNote;
        }

        public ServiceMember SaveServiceMember( ServiceMember serviceMember )
        {
            PersonBroker personBroker = new PersonBroker( this.ConnectionString );
            return personBroker.Save( serviceMember );
        }

        public Rank RankWith( long rankID )
        {
            ServiceBroker serviceBroker = new ServiceBroker( this.ConnectionString );
            return serviceBroker.RankWith( rankID );
        }
        #endregion

        #region Properties
        public PersonBroker PersonBroker
        {
            get
            {
                if( null == this.i_PersonBroker )
                {
                    this.i_PersonBroker = new PersonBroker( this.ConnectionString );
                }
                return i_PersonBroker;
            }
            set
            {
                i_PersonBroker = value;
            }
        }

        public ServiceBroker ServiceBroker
        {
            get
            {
                if( null == this.i_ServiceBroker )
                {
                    this.i_ServiceBroker = new ServiceBroker( this.ConnectionString );
                }
                return i_ServiceBroker;
            }
            set
            {
                i_ServiceBroker = value;
            }
        }
        #endregion

        #region Private Methods
        internal List<Grant> GrantsFor( ServiceMember serviceMember )
        {
            GrantBroker grantBroker = new GrantBroker( this.ConnectionString );
            return new List<Grant>( grantBroker.GrantsFor( serviceMember ) );
        }

        internal List<Case> CasesFor( ServiceMember serviceMember )
        {
            this.GrantsFor( serviceMember );
            return new List<Case>( serviceMember.Cases );
        }

        internal List<Note> NotesFor( ServiceMember serviceMember )
        {
            serviceMember.RemoveNotes();
            NoteBroker noteBroker = new NoteBroker( this.ConnectionString );
            List<Note> notes = noteBroker.NotesFor( serviceMember );
            notes.Sort( new Sorter<Note>( SortOrder.Descending, DEFAULT_NOTES_SORT ) );

            return notes;
        }
        #endregion

        #region Private Properties
        #endregion

        #region Construction and Finalization
        public ServiceMemberController()
            : base()
        {
        }
        #endregion

        #region Data Elements
        PersonBroker i_PersonBroker;
        ServiceBroker i_ServiceBroker;
        #endregion
    }
}
